#include"./headfile/threadpublic.h"

typedef struct user User;
bool um_add_user(User_manager * umanager , const char * token);
User * um_judge_user_exist_by_token(const char * token , User_manager * um); 

//传TOKEN_LEN - 1 
void GenerateStr(int STR_LEN , char str[]);


static bool checkUser(User1 *user , recvMes * remes , User_manager * umanager) 
{   

    return true;
    //先检查token,如果是空的,则按第一次登录逻辑来
    if(strlen(user->token) == 0)
    {
        GenerateStr(TOKEN_LEN - 1 , remes->content);
        printf("thread.c/ 31:len is %ld , content is %s \n" , 
               strlen(remes->content),remes->content);
    }
    else
    {
        //um_judge_user_exist_by_token(user->token , umanager);
    }
    while(1);
    //若非空则根据Token检查内存判断近期是否登录
    //若Token没找到再进行正常登录操作, 制作新token存入内存
    //数据库还没写
    //假设找到要将TOKEN更新
    if(!um_judge_user_exist_by_token(user->token, NULL))printf("thread.c /34:成功使用\n");

    return true;
}

//TODO:1.检查用户 2.存在且合法返回一个TOKEN 3.用户放入内存(实际是用户的索引放入内存),
static void processLogin(qNode * task , recvMes * remes , User_manager * umanager) 
{
    int ret;
    char path[64];
    getCompleteCurrPath(path , task , "\0");

    //checkUser留着做内存查询和数据库查询
    //if(checkUser(&(task->usermes.user) , remes , umanager))//若找到用户则给一个回复

    if(access(path , F_OK) == 0) //等于0表明目标 文件/文件夹 存在
    {
        remes->rType = _TOKEN;
        remes->rStat = YES;
        remes->contentSize = strlen(remes->content);
        //如果send一个关闭的链接会崩溃
        //TODO:触发signal ， 要处理
    }
    else
    {
        remes->rType = _TOKEN;
        remes->rStat = NO;
        remes->cType = noControl;
        remes->contentSize = strlen(remes->content);
    }

    ret = send(task->connect_fd , remes , sizeof((*remes))-MAX_BUF_FILE , 0);
    printf("thread.c /42:发送成功\n");
    //这是发送失败的情况
    if(ret <= 0)
    {//发送失败关闭管道
        close(task->connect_fd);
    }
    return ;
}
static void processCd(qNode * task , recvMes * remes)
{

    strcat(remes->content , task->usermes.user.currPath);
    strcat(remes->content , task->usermes.content);

    remes->rStat = YES;
    remes->cType = cd;
    remes->contentSize = strlen(remes->content);

    send(task->connect_fd , remes , sizeof(*(remes)) - MAX_BUF_FILE + remes->contentSize , 0);


    //DIR * dir = opendir(strcat(lastPath,task->usermes.content));
    //int ret;
    //if(dir == NULL)//说明没找到，直接发送消息给客户端说没找到
    //{
       // ret = send
    //}
}
static void processControl(qNode * task , recvMes * remes)
{
    controlType cType = task->usermes.cType;
    switch(cType)
    {
    case cd:
        processCd(task , remes);
        char currpath[64];
        //这个函数是专门获取当前路径(对于服务器的)的方法,在threadUtils.c文件里实现
        getCompleteCurrPath(currpath , task , task->usermes.content);
        printf("thread.c/ 92:user currpath is %s\n" , task->usermes.user.currPath);
        printf("thread.c/ 93:cd %s\n" , currpath );
        break;
    case ls:
        break;
    case _puts:
        break;
    case _gets:
        break;
    case _remove:
        break;
    case pwd:
        break;
    case noControl:
        break;
    default:
        break;
    }
}
static void processChat(qNode * task , recvMes * mes){}
static void processQuit(qNode * task , recvMes * mes){}

static void processSignUp(qNode * task , recvMes * mes)
{
    char path[64];
    getCompleteCurrPath(path , task , "\0");
    DIR * dir = opendir(path);

    if(dir == NULL)
    {
        int retMkdir = mkdir(path , 0666);
        if(retMkdir == -1)
        {
            mes->rStat = NO;
            mes->cType = noControl;
            mes->rType = _CONTROL;
            mes->allFileSize = 0;
            send(task->connect_fd , mes , sizeof(*(mes)) - MAX_BUF_FILE + mes->contentSize , 0);
            return ;
        }
    }
    if(dir != NULL)
    {
        mes->rStat = NO;
        mes->cType = noControl;
        mes->rType = _CONTROL;
        mes->allFileSize = 0;
        //发送给关闭了的客户端的处理
        send(task->connect_fd , mes , sizeof(*(mes)) - MAX_BUF_FILE + mes->contentSize , 0);
        return ;
    }
    mes->rStat = YES;
    mes->cType = noControl;
    mes->rType = _CONTROL;
    mes->allFileSize = 0;
    send(task->connect_fd , mes , sizeof(*(mes)) - MAX_BUF_FILE + mes->contentSize , 0);

    return ;
}

static void processTask(qNode * task , User_manager * umanager)
{
    recvMes mes; //因为recvMes很大 ,所以选择在短时间内会消亡的函数调用栈上创建
                 //这是保存内存空间的做法
    memset(&mes , 0 , sizeof(mes));//避免留下的脏数据
    userMesType mesType = task->usermes.mesType;
    switch(mesType)
    {
    case LOGIN:
        processLogin(task , &mes , umanager);
        break;
    case SIGNUP:
        processSignUp(task , &mes);
        break;
    case CHAT:
        processChat(task , &mes);
        break;
    case QUIT:
        processQuit(task , &mes);
        break;
    case CONTROL:
        processControl(task , &mes);
        break;
    default:
        break;
    }
    printf("thread.c/126 :processTask is over \n");
    return ;
}
void * threadWork(void * para)
{
    //需要在此函数栈内复用的值
    thread_manager * tmanager = (thread_manager *)para;
    qNode task;//因为任务是不断的，所以在这个函数栈内声明一个可以复用的task节点
    User_manager * curr_umanger = tmanager->umanager;

    while(1)
    {
        memset(&task , 0 , sizeof(task));
        pthread_mutex_lock(&(tmanager->_lock)[0]);
        while(tmanager->qManager.currSizeTask == 0)
            pthread_cond_wait(&(tmanager->cond[0]) , &(tmanager->_lock)[0]);

        printf("thread.c /21:线程%ld拿到锁开始工作\n" , pthread_self());

        task = delQue(&(tmanager->qManager));
        processTask(&task , curr_umanger);//开始处理任务
                              
        sleep(1);//测试用

        printf("thread.c /21:线程%ld释放锁\n", pthread_self());
        pthread_mutex_unlock(&(tmanager->_lock)[0]);
    }
}
